import json
import os
from typing import Annotated, Optional
from fastapi import APIRouter, Depends, Request
from fastapi.responses import FileResponse
from hashlib import md5

from application.config import appSettings
from sanren.extensions import ExtRedis
from sanren.utils import get_current_active_user
from application.http.models import OemModel
from application.http import schemas


router = APIRouter(prefix='/system', tags=['System'])
module_name = '系统模块 - 下载单'


@router.get('/downloads', response_model=schemas.BaseApiListOut)
async def get_dwonloads(
    current_user: Annotated[object, Depends(get_current_active_user)],
    request: Request,
    page_params: schemas.PageParams = Depends(),
    brand_id: Optional[int] = None,
    type: Optional[int | str] = None,
    status: Optional[int | str] = None,
    position: Optional[int | str] = None,
    keyword: Optional[str] = None,
):
    """
        下载单 列表
    """

    objs = OemModel.Download

    if brand_id:
        objs = objs.where('brand_id', brand_id)

    if type is not None and type != '':
        objs = objs.where('type', type)

    if status is not None and status != '':
        objs = objs.where('status', status)

    if position is not None and position != '':
        objs = objs.where('position', position)

    if keyword:
        objs = objs.where(
            lambda query: query.where(
                'name', 'like', f'%{keyword}%'
            ).or_where(
                'path', 'like', f'%{keyword}%'
            ).or_where(
                'remarks', 'like', f'%{keyword}%'
            )
        )

    objs = objs.order_by('id', 'desc').paginate(page_params.pageSize, page_params.page)

    return objs.serialize()


@router.get('/downloads/{id}', response_model=schemas.BaseApiListOut)
async def get_dwonload(
    current_user: Annotated[object, Depends(get_current_active_user)],
    request: Request,
    id: int,
):
    obj = OemModel.Download.find(id)
    if obj is None:
        return schemas.BaseApiOut(code=404, message='未找到此下载单')

    types = {1: 'export', 2: 'formcollection'}

    key_str = {
        'id': id,
        'type': types[obj.type],
        'path': obj.path,
    }
    md5_str = json.dumps(key_str, sort_keys=True).encode("utf-8")
    key = md5(md5_str).hexdigest()

    # 缓存 key 5分钟
    redis = ExtRedis().instance()
    redis.set(key, json.dumps(key_str), ex=60 * 60 * 24)

    # 返回download_url
    return schemas.BaseApiOut(data={
        'download_url': f'//{appSettings.web_host}/api/system/downloads/file/{key}'
    })


@router.get('/downloads/file/{token}', response_model=schemas.BaseApiListOut)
async def dwonload_file(
    request: Request,
    token: str,
):
    redis = ExtRedis().instance()
    params_str = redis.get(token)
    if params_str is None:
        return schemas.BaseApiOut(code=1, message='找不到此记录')

    params = json.loads(params_str)

    obj = OemModel.Download.find(params['id'])
    if obj is None:
        return schemas.BaseApiOut(code=1, message='找不到此记录')

    # 导出按类型读取文件
    if params['type'] == 'export':
        export_path = appSettings.export_path
        file_name = obj.path
        save_file_path = export_path + '/' + file_name

        if os.path.exists(save_file_path):
            return FileResponse(save_file_path, filename=file_name)
    elif params['type'] == 'formcollection':
        # 表单收集数据下载
        export_path = appSettings.export_path
        file_name = obj.path
        save_file_path = export_path + '/' + file_name

        if os.path.exists(save_file_path):
            return FileResponse(save_file_path, filename=file_name)

    return schemas.BaseApiOut(code=1, message='找不到文件')
